package com.yunhe.authority.service.authority;

import com.github.stuxuhai.jpinyin.PinyinException;
import com.yunhe.authority.domain.authority.Project;
import com.yunhe.authority.domain.authority.ProjectData;
import com.yunhe.authority.domain.authority.ResourceTree;
import com.yunhe.common.model.PageParam;
import com.yunhe.authority.domain.authority.Station;
import com.yunhe.authority.domain.base.StationType;
import com.yunhe.common.exception.ArgumentErrorException;
import com.yunhe.common.exception.DatabaseProcessException;
import com.yunhe.common.exception.ObjectNotFoundException;
import com.yunhe.common.exception.UniqueConstraintsException;
import com.yunhe.common.model.DomainList;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 电站Service
 * @desc 电站服务类定义
 * @author liuronglei
 */
public interface StationService {

    /**
     * 新增电站
     * @param station 电站对象
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    Station createStation(Station station, Long firmCode)
            throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException, PinyinException, IOException;

    /**
     * 删除电站
     * @param id 电站对象ID
     */
    @Transactional
    void deleteStation(Long id);

    /**
     * 更新电站
     * @param station 电站对象
     */
    @Transactional
    Station updateStation(Long firmCode, Station station)
            throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException, IOException;

    /**
     * 更新电站（更新指定字段）
     * @param id 电站ID
     * @param code 电站代码
     * @param StationCode
     * @param name 电站编号
     * @param title 电站名称
     * @param storageCapacity 储能装机容量
     * @param photovoltaicCapacity 光伏装机容量
     * @param windCapacity 风机装机容量
     * @param longitude 经度
     * @param latitude 纬度
     * @param sn 排序
     * @param productionTime
     * @param stationTypeCode 电站类型代码
     * @param areaCode 地区代码
     * @param activity 是否可用
     */
    @Transactional
    Station updateStation(Long id,
                          Long code,
                          Long StationCode,
                          String name,
                          String title,
                          Double storageCapacity,
                          Double photovoltaicCapacity,
                          Double windCapacity,
                          String longitude,
                          String latitude,
                          String sn,
                          Date productionTime,
                          Long stationTypeCode,
                          Long areaCode,
                          Boolean activity,
                          String coordinateRange,
                          String schematicDiagramBase64)
            throws ArgumentErrorException, ObjectNotFoundException, UniqueConstraintsException, IOException;

    /**
     * 更新电站类型
     * @param id 电站ID
     * @param stationTypeId 电站类型ID
     */
    void updateStationTypeById(Long id, Long stationTypeId) throws ObjectNotFoundException;

    /**
     * 根据电站ID获得电站
     * @param id 电站ID
     */
    Station findById(Long id);

    /**
     * 根据电站编号获得电站
     * @param name 电站编号
     */
    Station findByName(String name);

    /**
     * 根据电站代码获得电站
     * @param code 电站代码
     */
    Station findByCode(Long code);

    /**
     * 根据条件获得电站列表
     * @param firmCode 单位代码
     * @param typeCode 电站类型代码
     * @param queryStr 查询参数
     * @param pageParam 分页条件
     */
    Iterable<Station> findStations(Long firmCode,
                                   Long typeCode,
                                   String queryStr,
                                   PageParam pageParam);

    /**
     * 电站绑定资源
     * @param id 电站ID
     * @param type 资源类型
     * @param resourceId 资源ID
     */
    @Transactional
    void bindResource(Long id, String type, Long resourceId) throws ArgumentErrorException;

    /**
     * 解绑资源
     * @param id 电站ID
     * @param resourceId 资源ID
     */
    @Transactional
    void unbindResource(Long id, Long resourceId);

    /**
     * 批量更新资源绑定
     * @param id 单位ID
     * @param domainList 资源列表
     */
    @Transactional
    void updateResource(Long id, DomainList<ResourceTree> domainList)
            throws DatabaseProcessException;

    /**
     * 根据电站ID获得资源树
     * @param StationId 电站ID
     * @param typeList 类型列表
     */
    Iterable<ResourceTree> findResourceTreeById(Long StationId, List<String> typeList);

    /**
     * 根据电站ID获得电站代码
     * @param id 电站ID
     */
    Long getStationCodeById(Long id) throws ObjectNotFoundException;

    /**
     * 根据电站ID获得电站编号
     * @param id 电站ID
     */
    String getStationNameById(Long id) throws ObjectNotFoundException;

    /**
     * 根据电站ID获得电站类型
     * @param id 电站ID
     */
    StationType findStationTypeById(Long id);

    /**
     * 根据电站类型获得电站
     * @param stationTypeId 电站类型ID
     */
    Iterable<Station> findStationsByStationTypeId(Long stationTypeId);

    /**
     * 判断设备是否被绑定电站
     * @param devIdList 设备ID列表
     */
    Map<Long, Boolean> isBindStation(List<Long> devIdList);

    /**
     * 根据设备代码查找所属电站
     * @param devCode 设备代码
     */
    Station findStationByDevCode(Long devCode);

    /**
     * 查找单位下未被电站绑定的设备
     * @param firmId 单位ID
     */
    Iterable<ResourceTree> findDevicesUnbindStation(Long firmId);

    Long findTotalCount(Long firmCode,
                        Long typeCode,
                        String queryStr);

    Iterable<Station> findByRoleId(Long roleId);

    Iterable<Station> findOptionalByRoleId(Long roleId);

    Iterable<Station> findByFirmId(Long firmId);

    Iterable<Station> findByTitleContaining(String title);

    Iterable<Station> findByCapacity(Double capacity);

    /**
     * 根据代码列表获得电站列表
     * @param codeList 代码列表
     */
    Iterable<Station> findStationByCodes(List<Long> codeList);

    Station findByResourceId(Long resId);

    Iterable<Station> getStationsByRoleAndFirm(Long roleId, Long firmId);

    /**
     * 绑定电站拥有的企业
     * @param id 电站ID
     * @param companyId 企业ID
     */
    void bindCompany(Long id, Long companyId);

    /**
     * 解绑电站拥有的电站
     * @param id 电站ID
     * @param companyId 企业ID
     */
    void unbindCompany(Long id, Long companyId);

    Iterable<Station> findByRoleIds(List<Long> roleIds);

    /**
     * 根据指定字段更新电站
     * @param id
     * @param firmId
     * @return
     * @throws ObjectNotFoundException
     */
    Station updateStation(Long id, Long firmId, Project project) throws ObjectNotFoundException, UniqueConstraintsException, ArgumentErrorException, IOException;
    Station findByTitle(String title);


    /**
     * 根据公司ID查找所属电站
     * @param id 公司id
     */
    Station findStationByBindCompanyId(Long id);

    Station findByEnterpriseFullName(String stationTitle);

    /**
     *  获取当前登录人所在的园区或下面所有的园区
     *  @return
     * @param firmId
     * @param stationId
     */
    List<ProjectData> findStationByLoginUser(Long firmId, Long stationId) throws ArgumentErrorException;

    List<Map<String, Object>> getAllFirmAndStation(String system);

    /**
     * 根据真实园区ID查询总园区
     * @param realStationId 真实园区ID
     * @return Station
     */
    Station findStationByRealStationId(Long realStationId);
}
